home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
fish
/
676-700
/
699
/
ezasm
/
ezasm.doc
< prev
next >
Wrap
Text File
|
1995-03-18
|
31KB
|
1,360 lines
EZAsm Version 1.7 June '92 by Joe Siebenmann
DISCLAIMER:
The following only applies to EZAsm, ez.lib, fnm1, fdat1,
and related .doc files. ( A68k & Blink have their own
distribution policies )
You have the right to freely use, copy and distribute this program
as long as the following conditions are met:
1. The documentation is included with the program, and neither
is modified in any way.
2. The program is not included in any package for profit
unless written consent from the author is obtained.
Inclusion in a PD series is OK as long as the charge
( for disk, copying etc. ) is REASONABLE.
NOTE: The author does not accept any responsibility for any damage
that might result from the use of this program.
--- New for Version 1.7 ---
o Support for .fd's. Now you can directly use all the functions
in reqtools.library, req.library and others!
o All needed libraries including .fd's and resources
are opened and closed AUTOMATICALLY!
o Ez.lib updated with new functions. All arguments are now
pushed on the stack to avoid register corruption.
o The Exclusive-OR operator "x=" has been replaced with the more
traditional "^=", and a new "!=" for bit test.
o Support for 68020 and 68030 addressing modes.
o New local, and now GLOBAL optimizations!
EZAsm was written to make programming in 680X0 assembly
language MUCH easier! EZAsm combines 680X0 assembly language
with parts of C. The result is highly optimized code,
with almost HALF the development time!
A68k ( by Charlie Gibbs ) and Blink ( from The Software Distillery )
are included, and the offsets for all the 2.04 functions are
internal, so you'll have everything you need to start
producing executables. ( except the include files )
Here are some of its advantages:
o Your code is converted into the fastest possible
assembly statement(s), so you automatically write
"good" code.
o More structured. Compare and bit test statements can have
braces and "else" like C. Being able to use braces lets
you use assembly language in a whole new way!
o C-like Amiga function calls! Every 2.04 function in every
library is supported.
o Your code is much more readable, and easier to debug.
You can code nearly twice as fast, with fewer syntax errors.
o No more having to constantly look up which condition code to
use for compares, bit tests, or maximum numbers for
"moveq" or "addq" etc.
o You can freely mix "EZAsm statements" with regular
assembly statements.
You need to know a little about assembly language and
C operators before you dive right in. If you're new to
68000 assembly language, I suggest looking at one of the
many available books on the subject. The included example
source programs can give you a good idea about:
o General statement syntax.
o Use of "l", "w", "b" size arguments.
o Using assembly statements in your code.
****************************************
Using EZAsm:
1. Create a directory, and copy these files into it:
EZAsm, A68k, Blink, Mk, ez.lib, fnm1, fdat1
2. CD into your new directory, and you're ready to go!
( Another good method is to create an ALIAS to load these
files into VD0: and work from there )
Mk
Mk is a "make" like program, written in EZAsm, that will
Execute() the necessary programs for you, creating an
executable file with a minimum of effort. It also
supports an optional include path for A68k, and support
for a ".mak" file. The source code is included.
( WShell users might need to rename Mk )
Usage:
Mk [-iPathToIncludes] [path]file
( where "file" is your source file with path if needed
( No extension ))
Execute()'s these commands:
ezasm file.s
a68k [-iPathToIncludes] file.asm
blink FROM file.o LIB ez.lib TO file
.mak
For times when you need to supply more options for A68k or
Blink, or invoke other assemblers or linkers, Mk supports
a .mak file. Just create a file with the same name as your
source file, but with a ".mak" extension. The file should
contain the EZAsm, A68k, Blink or other commands, with any options
or switches you need, as if you were entering them from the CLI.
Any comments should begin with a non-alpha character.
If Mk finds the .mak file, it will Execute() those commands,
otherwise it will Execute() the standard commands.
***************************************
* Addressing Modes *
***************************************
Operand Type
Mode [A] [B] [C] [D] [E] [F]
Dn * * * - * -
An * - * - - -
(An) * * * * * *
(An)+ * * * * * *
-(An) * * * * * *
d16(An) * * * * * *
d8(An,Xn) * * * * * *
16 bit addr * * * * * *
32 bit addr * * * * * *
d16(PC) * - - - * *
d8(PC,Xn) * - - - * *
immediate * - - - * -
bd(An,Xn) * * * * * * 68020/68030
([bd,An],Xn,od) * * * * * * 68020/68030
([bd,An,Xn],od) * * * * * * 68020/68030
bd(PC,Xn) * - - - * * 68020/68030
([bd,PC],Xn,od) * - - - * * 68020/68030
([bd,PC,Xn],od) * - - - * * 68020/68030
declared variables:
"foo" becomes "foo(a5)" ( d16(An) )
**************************************
<1-8> 1 - 8
<q> -128 - 127
<n> any byte, word, or long size number
Dn d0 - d7
An a0 - a7
bd 32 bit displacement
od 32 bit outer displacement
Xn a0 - a7 d0 - d7 Options: Examples:
size: .w .l a2.w a0.l
scale: *1 *2 *4 *8 a1*2 a0.w*4 ( 68020/68030 )
{B} byte data size not allowed for An operands
**********************************
* legal * legal *
* operands * sizes *
**********************************
Addition Subtraction
++
--
[C] <op> L,W,{B} *
+=
-=
Dn <op> [A] L,W,B
An <op> [A] L,W *
[D] <op> Dn L,W,B
[B] <op> <n> L,W,B
[C] <op> <1-8> L,W,{B} *
Examples:
Total ++
d1 += 10
Optional Args:
l, w, b
* These are now better optimized by making the size word (.w)
instead of long (.l) for "An" operands. Its takes 4 less
cycles, and the upper two bytes are correctly handled!
********************************************
Multiplication Division
*=
Dn *= [E] W
Dn *= ## W *
/=
Dn /= [E] W
Examples:
d0 *= d1
d2 /= 2
Optional Args:
w,
s ( signed divs/muls )
* This optimization results in code that's larger then "mulu"
or "muls", but will execute much faster. Not all numbers
can be optimized. If the number doesn't work, "mulu"
or "muls" will be used.
( where ## is a word or byte length number )
*********************************************
And Or Exclusive-OR
&=
|=
Dn <op> [E] L,W,B
[B] <op> <n> L,W,B
[D] <op> Dn L,W,B
^=
[B] <op> Dn L,W,B
[B] <op> <n> L,W,B
Examples:
Mask &= %11010000
Flags |= $f0
Optional Args:
l, w, b
*********************************************
Shift Left/Right
<<
>>
Dn <op> Dn L,W,B
Dn <op> 1-31 L *
Dn <op> 1-8 L,W,B
[D] <op> 1 W
Examples:
d2 << d0
d1 >> 4
Optional Args:
l, w, b,
a ( arithmetic shift asl/asr )
* Normally you're limited to shifting 1-8, or using a
data register to hold higher. This optimized version
is faster, and saves using a data register!
( logical shift only )
*********************************************
Assign
=
[B] = [A] L,W,{B}
An = [A] L,W
Examples:
temp = Total
(a1)+ = 0 w
Optional Args:
l, w, b
********************************************
Compare
>=
<=
!=
>
<
=
Dn <op> [A] L,W,{B}
An <op> [A] L,W
[B] <op> <n> L,W,B
(An)+ <op> (An)+ L,W,B
Syntax types:
[opr] <op> [opr] label
[opr] <op> [opr] {
.
.
}
[opr] <op> [opr] {
.
.
} else {
.
.
}
Examples:
Total >= 101 Over
Buf != 0 {
FreeMem( Buf 100 )
}
(a0)+ = $20 {
SPCnt ++
} else {
ChrCnt ++
}
Optional Args: ( placed AFTER label or brace )
l, w, b,
s ( signed )
*********************************************
Bit test
=
!=
Dn:0-31 <op> 0-1 L
Dn:Dn <op> 0-1 L
[F]:0-7 <op> 0-1 B
[F]:Dn <op> 0-1 B
Syntax types:
[opr] <op> [opr] label
[opr] <op> [opr] {
.
.
}
[opr] <op> [opr] {
.
.
} else {
.
.
}
Examples:
d1:0 != 1 EvenRtn
($bfe001):6 = 0 LMBDown
d2:d0 = 1 {
rts
}
Optional Args:
( ignored )
Rules:
o No spaces inside first operand.
o Right operand can only be 0 or 1.
*********************************************
Additional Arguments:
b forces operation to be byte
w " " " word
l " " " long
a arithmetic shift ( <<, >> )
s signed ( *=, /=, compares )
( it's OK to use multiple arguments ( "w s" etc. ))
( these are RESERVED and can't be used as variables, or labels
( unless you use upper case ) )
*********************************************
Functions:
Syntax examples:
CloseWindow( Window )
Buf = AllocMem( 512 #CLEAR_PUBLIC )
Permit( )
Example:
--------------------------------
CLEAR_PUBLIC equ $10001
OLDFILE equ 1005
LONG FHandle num Rbuf
Rbuf = AllocMem( 100 #CLEAR_PUBLIC )
beq Exit
FHandle = Open( "df0:myfile" #OLDFILE )
beq Exit
d3 = 100 ; preload D3
num = Read( d0 Rbuf * )
.
.
.
---------------------------------
o All 2.04 functions are now supported.
Don't worry, the older 1.3 functions are still there.
Some 2.04 functions are "for internal use only",
some "OBSOLETE". Check "fnm1" for supported functions.
( AllocWBObject( ), FreeWBObject( ), GetWBObject( ),
PutWBObject( ) in IconBase, are listed as "OBSOLETE"
but are still included )
Tag Lists:
The "varargs" versions of tag list functions are not
supported, only the versions that take a pointer to a
tag list are supported.
o All needed libraries including .fd's and resources
are opened and closed AUTOMATICALLY, and their bases
are added to your variables. ( resources don't need to
be closed )
All functions within these 2.04 libraries and resources
are supported:
amigaguide.library _AmigaGuideBase
asl.library _AslBase
battclock.resource _BattClockBase
battmem.resource _BattMemBase
ciaa.resource _CiaABase
ciab.resource _CiaBBase
commodities.library _CxBase
disk.resource _DiskBase
diskfont.library _DiskFontBase
dos.library _DosBase
exec.library
expansion.library _ExpansionBase
gadtools.library _GadToolsBase
graphics.library _GfxBase
icon.library _IconBase
iffparse.library _IFFParseBase
intuition.library _IntuitionBase
keymap.library _KeymapBase
layers.library _LayersBase
mathffp.library _MathBase
mathieeedoubbas.library _MathIeeeDoubBasBase
mathieeedoubtrans.library _MathIeeeDoubTransBase
mathieeesingbas.library _MathIeeeSingBasBase
mathieeesingtrans.library _MathIeeeSingTransBase
mathtrans.library _MathTransBase
misc.resource _MiscBase
potgo.resource _PotgoBase
rexxsyslib.library _RexxSysBase
translator.library _TranslatorBase
utility.library _UtilityBase
workbench.library _WorkbenchBase
All functions for these .devices are supported:
console.device _ConsoleBase
input.device _InputBase
ramdrive.device _RamDriveBase
timer.device _TimerBase
You're responsible for calling OpenDevice( ) and
loading the base to use these .device functions:
LONG _TimerBase TimeRequest
TimeRequest = AllocMem( 40 #CLEAR_PUBLIC )
beq Exit
OpenDevice( "timer.device" 0 TimeRequest 0 )
bne Exit
a0 = TimeRequest
_TimerBase = 20(a0) ;TimeRequest->tr_node.io_Device
.
.
o The cia.resource functions AbleICR( ), AddICRVector( ),
RemICRVector( ), and SetICR( ) have been changed to
simplify the OpenResource( ). The functions are now
AbleICRA( ) and AbleICRB( ) etc. and open the corresponding
ciaa.resource and ciab.resource.
o The leading underscores of the bases are necessary so you can
use includes without your assembler complaining. Some library
bases are already defined in some .i's resulting in
"multiply defined symbol" errors.
Permit( )
AllocMem( 100 #CLEAR_PUBLIC )
^ ^ ^
no space | | space | space
o The function name must be followed immediately with "("
( no spaces between ) and then followed by a space or tab.
If the function has no arguments, it still needs a space in
the middle. Arguments must be separated with a space or tab.
a2 = ViewAddress( )
d1 = Read( "myfile" Buf BufLen )
o Address or data registers can be used for returns if
they're more convenient. Returns to D0 are now back in.
Return variables can now be ANY size. Variables used in
function arguments must be LONG.
o Several people were concerned when their OpenWindow( ) and
OpenScreen( ) calls crashed. The included example source
"scrwin.s" opens a screen and a window, and is a good
"base" for starting similar programs. Problems occur
when the NewWindow fields "IDCMPFlags" and "Flags" are
incorrectly switched, the structure isn't word aligned,
or fields are the wrong size.
( also include any filler "kludge" bytes )
Arguments:
o If your argument is already in a DIFFERENT data or address register,
you can pass it as an argument directly. Often a previous function
will put results in D0, so just pass d0. If the proper
register is already loaded, just pass "*".
( if you pass it the same register it uses, it'll be skipped.
func defined as: D0 = Lock( D1 D2 ) "Flock = Lock( d1 -2 )"
arg "d1" will be skipped ( it's already loaded ))
o You can also use other addressing modes for function arguments
and returns. ( "(An)", "(An)+", "-(An)", "d16(An)" etc. )
o EZAsm supports argument strings surrounded by double quotes.
Strings are automatically NULL terminated.
The following C character constants are supported:
\b backspace
\f form feed
\n newline
\r carriage return
\t horizontal tab
\v vertical tab
Examples:
"Hello, World!\n"
"\t\tHeading\n"
NewWin ds.w 0 ;align
dc.w 0,0,640,200
dc.b -1,-1
.
.
o To load a pointer to a NewWindow or other "structure" you've
defined ( above ) use: #NewWin ( etc. ) it'll load its address
into a data or address register.
o if you need a pointer to one of your declared variables
( where the argument goes to an address register ) use:
&foo ( address of "foo" )
( output as "lea foo(a5),An" )
( "&" is ONLY recognized inside function arguments )
o Sometimes you have to "play around" with using "#", "&", variables,
constants etc. You might be giving it the contents of a variable,
when it needs its address ( etc. )
o It keeps track of the current library base. As long as no user
labels, or close braces are hit, it will skip reloading
the base register for functions which use the same library base.
o The file "fnm1" contains a list of every function that is
supported.
*********************************************
Support for .fd's
Usage:
PROTO [path]LibraryName [path]FDName
Example:
PROTO req.library req.fd
Where PROTO is in upper case, begins at column 1, and
is placed ABOVE your variable declarations. The .fd
file is read, and all its functions, both "##public"
and "##private", become available for use. The
library base is added to your variables, and the
opening and closing of the library is handled
automatically.
To avoid any conflicts with other function names, these
are used first. Up to 10 .fd's can be used.
"PROTO" can be useful for replacing function argument
registers, or the offset ( if I happened to get one wrong )
or to add functions if a new version of a library comes
out.
Here's an example of a minimal .fd to replace Examine( )
in _DosBase :
##base _DosBase
##bias 102
Examine()(D1,D2) ;( arguments within the first "()" are ignored )
##end
( the default bias is 30 )
*********************************************
Using command line arguments:
Because the automatic opening of libraries will
corrupt A0 and D0, the following "switches" are provided:
( see Mk.s for an example of using "ARGS" )
ARGS
A0 is loaded into the variable "Args" ( automatically
created ) and "clr.b -1(a0,d0.w)" is used to NULL terminate
the argument string. The length in D0 is lost.
SAVEARGS
A0 and D0 are pushed onto the stack with "movem.l d0/a0,-(sp)".
You're responsible for restoring and using them.
SAVEREGS
Useful when calling an EZAsm assembly function from your
main C code. Pushes all registers, except D0, onto
the stack with "movem.l d1-d7/a0-a7,-(sp)" before the "link",
and restores them with "movem.l (sp)+,d1-d7/a0-a7" right before
exiting with "moveq #0,d0", "rts".
*********************************************
Optimizations:
In addition to the many "normal" optimizations performed
on statements, the following are also performed:
STATEMENT BECOMES NOTE
An = 0 sub.l An,An
[B] = 0 clr [B] 1
( compares )
[B] < 0
[B] >= 0 5
[B] = 0
[B] != 0 tst [B] 6
bxx label
----------------------------------
[B] += <q>
[B] -= <q>
[B] &= <q>
[B] |= <q>
[B] ^= <q>
[B] = <q> moveq <q>,d7 2
[opr].l d7,[B]
( compares )
Dn <op> <q> moveq <q>,d7 2
cmp.l d7,dn
bxx label
An <op> <q> moveq <q>,d7 2
cmpa.l d7,an
bxx label
----------------------------------
An += <i> lea i(An),An
An -= <i> lea -i(An),An 3, 2
An = <n> lea n,An 4, 2
<i> maximum: -= 32768 += 32767
Notes:
1 For byte and word sizes the code size is smaller, for long,
its smaller and faster. ( then "move #0,[B]" )
2 Only apply to long sized operations.
3 ( 1-8 handled by "addq", "subq" ( see note in Addition Subtraction ))
4 ( 0 handled by "sub.l An,An" )
5 Taken as signed.
6 In some cases "tst" is eliminated, or D7 is loaded, see below.
New GLOBAL optimizations:
Buf != 0 {
FreeMem( Buf 100 )
}
( before ) ( now )
tst.l Buf(a5) move.l Buf(a5),d7
beq .l2 beq .l2
movea.l $4,a6 movea.l $4,a6
movea.l Buf(a5),a1 movea.l d7,a1
. .
. .
o Instead of doing a "tst", the variable is loaded into D7
( flags set, and same size and number of cycles ) where it can
be utilized by a following function call. In this case it
loads D7 into A1, saving 2 bytes, and taking only 4 cycles
instead of 13.
Fhandle = Open( "df0:myfile" 1005 )
Fhandle = 0 {
.
.
}
. .
. .
move.l d0,Fhandle(a5) move.l d0,Fhandle(a5)
tst.l Fhandle(a5) bne .l5
bne .l5
o The flags are set by the "move", so the "tst" instruction
can be eliminated, saving 4 bytes and 9 cycles.
( a label before the "Fhandle = 0 {" statement disables this )
*********************************************
General Info:
o Statements can be indented as you like. Operands, operator,
and arguments must be separated by at least one space or tab.
o Braces can be nested up to 30 deep.
o Only one statement per line.
o If you declare variables or use function call's, the first statement
in your code must be an "EZAsm statement" so it knows when
to insert the XREF's and/or get stack frame for the
variables. Comments, assembly directives, or assembly statements
placed between your variables and the start of your code will be
OUT OF PLACE in the output file.
o Comments must begin with "*" or ";" and begin at column 1, or after
statements ( separated from last argument or operand ) using ";".
( both types are transferred to the output file ( some may not ))
o Operands supported: @141 (octal), $61 (hex), %1100001 (binary),
'a' (ASCII), 97 (decimal). ASCII strings in operands can
contain a maximum of 4 characters.
( no quotes within quotes permitted )
o To make labels and symbols as compatible as possible, they arn't
checked for illegal characters. Typically the 1st character
must be a letter, underscore "_", or a period "." .
The rest of the characters can be any of these plus 0-9.
o Labels and symbols are limited to a length of 127.
( Check your assembler to find what length they're
significant to ( usually around 30 ))
o Labels that don't begin at column 1 must be followed immediately
with ":".
o Temporary labels of the form n$, where n consists of decimal
digit(s), are supported. These labels are only in effect till
the next non-temporary label is encountered. ( be careful
of "hidden" labels generated by braces )
o "moveq #0,d0", "rts" is automatically inserted for you in the
closing block of code.
o D7 is used as a scratch register for many optimizations, so be
careful if you use it.
o Labels that it generates for braces are in the range:
.l0 to .ln . This is new, and allows for an unlimited number of
labels. Try to avoid accidentally using them.
o Constants generated from argument strings are in the range:
.c0 to .cn . Matching strings are not duplicated.
o "SP", "PC", "CCR", "SR" & "USP" ( upper or lower case )
are supported, but you must ensure the size etc. is legal.
o For best viewing of the output file, set your tabs to 8 spaces.
( printing should be fine )
IMPORTANT! :
Use of register A5 is RESERVED!
( it contains the base address for variable storage )
*********************************************
Variable Declaration:
LONG foo Save[10] bar
WORD DMASave
BYTE Sw
o "xxx[n]" reserves n consecutive blocks of given size,
with "xxx" pointing to the left-most byte.
( this is for advanced users who need a convenient
way to allocate SMALL chunks of memory for saving
registers etc. )
o You're limited to 14 variables per line.
o No other statement types may occur between these lines.
o Variables must be separated by at least one space, or tab.
o To keep things word aligned, if an odd number of variables are
declared in BYTE, an extra byte will be added.
( this will offset the next "equ" by one )
o Declarations must occur JUST BEFORE your program code,
and begin at column 1, with LONG, WORD, or BYTE in upper case.
o EZAsm uses "link" to allocate space for variables on the stack.
The maximum size of this space is 32K. Since this stack space
contains "garbage", code is added to clear it out before use.
What the stack frame looks like:
LONG foo
WORD bar Total
LONG Cnt
becomes...
foo equ -4
bar equ -6
Total equ -8
Cnt equ -12
h l A5 base register
i o |
OOOO OO OO OOOOO memory bytes
(-) 1119 87 65 4321
210
( Sometimes variables are "adjusted" for proper loading, and
"-2(a5)" or other displacement may appear in the output file
instead of "foo(a5)" or other variable name you might be expecting. )
*********************************************
General Info:
END
Data statements ( "dc.b", "ds.l" etc. ) should be
placed BELOW the "END" statement. Any string
constants which are generated will also appear
below the "END". Other statements ( "equ",
"xref", "xdef" etc. ) can be placed ABOVE your
variable declarations, or BELOW "END".
( In the final .asm file "END" will be adjusted )
o Instruction size: In most cases you WON'T NEED
A SIZE ARGUMENT. It knows the size of your variables,
address and data registers, and is smart enough to know
what size to use. You'll need to specify a size if
the data is smaller than the instruction size you want,
( d1 = $20 w ) or it can't know the size of the operands
( (a2)+ = 3(a0) l ).
Caution: Be aware that if you load small variables into
larger ones, the upper bytes arn't cleared and
may garbage your result. Always initialize those
variables, or restrict the size of further
operations to "b" or "w".
o Try not to overuse the size arguments. Once you get confident
it's sizing your instructions correctly ( by checking the
.asm file ) you'll find you can eliminate their use almost
entirely. By needlessly restricting a long operation to
a word, or byte, you can miss the "quick" optimization.
o Since "(a1)" refers to the CONTENTS of the byte, word, or long
that A1 points to, "($dff180)" is used in a similar way.
( decimal addr's are also valid: "(14675968)" )
o When numbers are used as operands "$fe02" or "37", they are
converted to "#$fe02" and "#37". Operands that it
doesn't recognize ( doesn't match with any declared
LONG, WORD, BYTE, or standard "(a1)+" etc. ) get output
as is. This is very useful when you need operands
like: "#NewWin", "wd_UserPort(a1)", "$20(a1)", "DMACON(a3)"
o Most instructions set condition code flags on the result of the
operation. Often, instead of using a compare to check the
result, you can use a branch on condition instruction ( "beq",
"bne" etc. ) to jump to a location on the state of a condition
code flag. You need to check which flags are set ( if any )
for an instruction.
o If at any time you're unsure of what a statement is being
output as, or want to check something out, just look
at the output file. Well placed blank lines in your source
code can enhance its readability.
o I think it's a good idea to get away from using include files.
Most assembly source files I see do this.
It speeds up the assembler tremendously, and saves
endless wear and tear on your drives.
****************************************************
Converting C to EZAsm:
Its fairly easy to convert any C code into
EZAsm if you follow these guidelines:
Allocating structures:
Whenever you see "struct VSprite SpriteA" etc.,
you need to either allocate some memory for the
structure, or set up your own:
CLEAR_PUBLIC equ $10001
LONG SpriteA
SpriteA = AllocMem( [structure size] #CLEAR_PUBLIC )
beq Exit
---------- or ----------------
SpriteA ds.w 0 ;align
dc.l 0 ;NextVSprite
dc.l 0 ;PrevVSprite
.
.
( you could use "#vs_SIZEOF" etc. for [structure size]
and let the assembler get its size from the includes )
Some functions will create the structures for you
and return a pointer to it ( OpenWindow( ), OpenScreen( )
etc. ) just declare a LONG, and load the returned pointer:
LONG Window
Window = OpenWindow( #NewWindow )
beq Exit
Referencing structures:
Often you'll need to get at data inside structures.
First load the "structure pointer" into an address
register, then use the offset of the structure element.
Here's a typical example:
Move( Window->RPort, 20, 20 ); /* C */
a0 = Window
Move( wd_RPort(a0) 20 20 )
---- or ----
a0 = Window
Move( 50(a0) 20 20 )
( add an include to your source, and the assembler
will look-up "wd_RPort" and substitute its offset or,
even better, use "50(a0)" instead of "wd_RPort(a0)" )
( it's Ok to use the same address register )
a0 = Window
a0 = wd_RPort(a0)
Loops:
I've often thought about trying to add at least a
while( ) like statement, but it's just as easy
to "code-your-own":
for ( foo = 0; foo < 10; foo++ ) { /* C */
}
LONG foo
foo = 0 ;initialization statements..
Again: . ;body..
.
foo < 10 { ;test, and other statements..
foo ++
jmp Again
}
Info:
If you try converting statements one-for-one in
complex C code, you can end up pulling your hair out,
and end up with tons of code. In cases like this,
take a step back, and try to figure out the "idea"
of what's going on, or what the final result will be,
then try to think how you'd code it using EZAsm.
I think you'll be surprised by the results!
*********************************************
Errors:
"Illegal argument"
The argument found was not valid for the operator. See
the list of "Optional Args" for the operator. It must
be lower case, and be separated from the operands
by at least a space or a tab.
"Illegal operand"
One, or both, of the operands are: not valid for the operator,
have an invalid number, or byte size was specified for an
"An" operand ( {B} ). In most cases it's looking for "Dn" or "An"
as one of the operands. ( look under the "legal operands"
of the operator for a valid combination )
"Illegal size"
The argument size you specified is not valid for the operator.
Check the "legal sizes" for the operator.
"Needs size argument"
It doesn't have enough size information about the operands to
calculate an instruction size.
You need to add an l, w, or b argument.
"Label not found"
No label matching your label argument was found.
"Brace mismatch"
Checks are made when a closing brace ( "}" ) is hit, and when "END"
is hit. If the brace stack is "messed up" at that time, an error
is given. If "}" is shown, look from there up. Both "}" and "END"
may appear. If just "END", look for a "{" or "} else {" without a
matching "}".
"Function not found"
No function matching your function name was found. Check case and
spelling of function name, and be sure there isn't a space before
the "(". Check the list of supported function names in the
file "fnm1".
"Function argument count incorrect"
Check the number of arguments you used for the function. Too many
or not enough were used. With string arguments, check for
a missing '"'. Also look for a missing end ")".
( EZAsm doesn't do much checking of normal assembly statements.
A68k and Blink will catch any problems missed by EZAsm and bring
them to your attention )
*******************************************************************
*******************************************************************
Try using EZAsm, I don't think you'll want to go back to
"ordinary" assembly language programming. 8^)
Why isn't EZAsm shareware? I don't think you can make much
money with shareware, and because I get a lot more satisfaction
knowing that people are using it. I think this is going to be
the last version, but if you have any problems, or just want
to say "hello", I'd like hearing from you!
Enjoy!
You can reach me at:
Joe Siebenmann
2204 Pimmit Run Lane Apt 1
Falls Church, VA 22043
( USA )
(703) 893-2579